package com.firefightingiot.firefightingiot.web.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.firefightingiot.firefightingiot.common.base.BaseService;
import com.firefightingiot.firefightingiot.model.IpSoundFileName;
import com.firefightingiot.firefightingiot.model.IpSoundPlaying;
import com.firefightingiot.firefightingiot.support.model.RespEntity;
import com.firefightingiot.firefightingiot.support.mybatisplus.QueryWrapper;
import com.firefightingiot.firefightingiot.web.mapper.IpSoundFileNameMapper;
import com.firefightingiot.firefightingiot.web.mapper.IpSoundPlayingMapper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
public class IPSoundColumnAsyncService extends BaseService {
    @Resource
    private IpSoundFileNameMapper ipSoundFileNameMapper;
    @Resource
    private IpSoundPlayingMapper ipSoundPlayingMapper;
    //UDPClient udpClient = new UDPClient();

    String headInit = "FEE0A7";
    String diD = "00001234";
    String cmd = "0F";

    //初始化头部
    public String initHeader(String diD, String cmd, String len0, String len1, String para) {
        diD = diD.substring(6, 8) + diD.substring(4, 6) + diD.substring(2, 4) + diD.substring(0, 2);
        String type = "8A";
        String sn = "0000";
        //帧头后的长度，小端
        //String para = "00";
        String accept = "00";
        //帧头算术和，取后两位
        String chkSum = "";
        String sum = makeChecksum(headInit + type + diD + sn + len0 + len1 + cmd + para + accept);
        int sumLength = sum.length();
        chkSum = sum.substring(sumLength - 2, sumLength);
        return headInit + type + diD + sn + len0 + len1 + cmd + para + accept + chkSum;
    }

    /**
     * 请求执行可编辑的播放任务
     * @return
     */
    public String requestEditableTask (String taskNumber,String timeMode, String timeType, String startTime, String entTime, String taskNameString,String playContentId, String playObjectId,int playNum) {
        //任务编号:可编辑任务00，定时任务FE taskNumber
        //String taskNumber = "00";
        //保留
        String baoLiuOne = "00";
        //任务类型: 0：文件播放 File,1：采播设备 Capture
        String taskType = "00";
        //定时类型和定时模式
        String timeTypeAndMode = "";
        //保留 timeTypeAndMode二进制
        String ttamBin7 = "0";
        String ttamBin6 = "0";
        //定时模式 Time Mode（起始时间的选项） ,01 绝对时间 Calendar,10 即时执行 Instant
        String ttamBin54 = "";
        //判断是否是可编辑任务或定时任务
        if (taskNumber.equals("00")) {
            if (timeMode.equals("Calendar")) {
                ttamBin54 = "01";
            } else if (timeMode.equals("Instant")) {
                ttamBin54 = "10";
            }
        } else if (taskNumber.equals("FE")) {
            if (timeMode.equals("WeekLoop")) {
                ttamBin54 = "00";
            } else if (timeMode.equals("Calendar")) {
                ttamBin54 = "01";
            }
        }

        String ttamBin32 = "00";
        //定时类型 Time Type（结束时间的选项）, 00 指定时刻 Time（结束时间无效） ,01 指定时段 Period
        String ttamBin10 = "";
        if (taskNumber.equals("00")) {
            if (timeType.equals("Time")) {
                ttamBin10 = "00";
            } else if (timeType.equals("Period")) {
                ttamBin10 = "01";
            }
        } else if (taskNumber.equals("FE")) {
            if (timeType.equals("Time")) {
                ttamBin10 = "00";
            } else if (timeType.equals("Period")) {
                ttamBin10 = "01";
            }
        }
        int i = Integer.parseInt(ttamBin7 + ttamBin6 + ttamBin54 + ttamBin32 + ttamBin10,2);
        timeTypeAndMode = hex10To16(i);
        //星期选项
        String week = "";
        if (taskNumber.equals("00")) {
            week = "00";
        } else if (taskNumber.equals("FE")) {
            //todo 周日-周一全天播放
            week = "FE";
        }
        //文件播放方式01循环播放，02顺序播放
        //String playbackMode = "01";
        //todo
        String playbackMode = "01";
        //播放内容的数量
        String playContentNumber = "02";
        //播放对象的数量
        //String playObjectNumber = "01";
        String playObjectNumber = "";
        String playNumHex = hex10To16(playNum);
        if (playNumHex.length() == 1) {
            playObjectNumber = "0" + playNumHex;
        } else {
            playObjectNumber = playNumHex;
        }
        //任务音量值任务的音量值，取值范围 0～127，单位-dB。0dB 是最大音量，值 127 对应-127dB 为最小音量。
        String taskVolume = "00";
        //提前打开功放时间
        String OpenAdvanceTime = "00";
        //保留2
        String baoLiuTwo = "00";
        //保留3
        String baoLiuThree = "00";
        //------------------------------------------------------------------------------
        //任务名称字符串
        int taskNameStringLength = taskNameString.length();
        String taskNameStringLengthString = "";
        if ((taskNameStringLength+"").length() == 1) {
            taskNameStringLengthString = "0" + taskNameStringLength;
        } else if ((taskNameStringLength+"").length() == 2) {
            taskNameStringLengthString = taskNameStringLength + "";
        }
        String taskName = stringToAscii(taskNameString).replace(",","");
        String heBing = taskNameStringLengthString + taskName;
        String ling = "";
        if (heBing.length() < 64) {
            int a = 64- heBing.length();
            for (int b = 0; b < a; b++) {
                ling += "0";
            }
        }
        taskNameString = heBing+ling;
        //播放内容编号表
        String playContent = playContentId;
        //播放目标编号表
        String playObject = playObjectId;
        String result = taskNumber + baoLiuOne + taskType + timeTypeAndMode + startTime + entTime + week + playbackMode + playContentNumber + playObjectNumber + taskVolume + OpenAdvanceTime + baoLiuTwo + baoLiuThree + taskNameString + playContent + playObject;
        System.out.println(result);
        return result;
    }


/*    public RespEntity publishAudioNew(JSONObject jsonParam) {
        //处理支持form-data和json两种方式
        jsonParam = HttpRequestUtil.commonHttpRequestParamConvert(getRequest());
        //调用token验证接口
        com.alibaba.fastjson.JSONObject token = makeDataForToken(jsonParam, "systemsetup", "config", "getDecodeToken", "systemsetup");
        if (StrUtil.isNotBlank(token.getString("methodCodeFlag"))) return RespEntity.expire();
        if (StrUtil.isNotBlank(token.getString("methodErrorFlag"))) return RespEntity.fail(token.getString("msg"));
        String devNums = jsonParam.getStr("devicenumber");
        String[] split = devNums.split(",");
        for (String s : split) {
            List<IpSoundPlaying> devicenumberList = this.ipSoundPlayingMapper.selectList(new QueryWrapper<IpSoundPlaying>().eq("devicenumber", s));
            if (devicenumberList.size() > 0) {
                //音乐已经自己结束了
                if (DateUtil.date().compareTo(devicenumberList.get(0).getEndtime()) > 0) {
                    String id = devicenumberList.get(0).getId();
                    this.ipSoundPlayingMapper.deleteById(id);
                } else {
                    return RespEntity.fail("请先终止设备" + devicenumberList.get(0).getDevicenumber() + "播放");
                }
            }

        }
        publishAudio(jsonParam);
        return RespEntity.success();
    }*/

    /**
     * 请求编辑执行任务
     * @param jsonParam
     * @return
     */
    //@Async
    public RespEntity publishAudio(JSONObject jsonParam) {
        String devNums = jsonParam.getStr("devicenumber");
        String[] split = devNums.split(",");
        /*for (String s : split) {
            List<IpSoundPlaying> devicenumberList = this.ipSoundPlayingMapper.selectList(new QueryWrapper<IpSoundPlaying>().eq("devicenumber", s));
            if (devicenumberList.size() > 0) {
                //音乐已经自己结束了
                if (DateUtil.date().compareTo(devicenumberList.get(0).getEndtime()) > 0) {
                    String id = devicenumberList.get(0).getId();
                    this.ipSoundPlayingMapper.deleteById(id);
                } else {
                    return RespEntity.fail("请先终止设备" + devicenumberList.get(0).getDevicenumber() + "播放");
                }
            }
        }*/

        Object[] objects = splitAry(split, 200);
        for (Object o : objects) {
            String filename = "";
            String subId = "";
            String idResList = "";
            String[] ids = (String[]) o;
            for (String id : ids) {
                String idRes = id.substring(6, 8) + id.substring(4, 6) + id.substring(2, 4) + id.substring(0, 2);
                idResList += idRes;
            }
            String filenumberOld = jsonParam.getStr("filenumber");
            String filenumber = jsonParam.getStr("filenumber");
            String starttime = jsonParam.getStr("starttime");
            String endtime = jsonParam.getStr("endtime");
            //2021-09-29 00:02:00
            //2021-09-29 12:42:00
            //2021-09-29 20:02:00
            //定时任务
            String taskNumber = "00";
            String timeMode = "Calendar";
            String timeType = "Period";
            String startTime = getHexTime(starttime);
            String endTime = getHexTime(endtime);
            String taskNameString = "TASK6789";
            String filenumber01 = filenumber.substring(0, 2);
            String filenumber02 = filenumber.substring(2, 4);
            filenumber = filenumber02 + filenumber01;
            String playContentId = filenumber+"0000";
            String playObjectId = idResList;
            String date = requestEditableTask(taskNumber, timeMode, timeType, startTime, endTime, taskNameString, playContentId, playObjectId,ids.length);
            String len = hex10To16((date.length()) / 2);
            String len0 = "";
            String len1 = "";
            if (len.length() == 2) {
                len0 = len;
                len1 = "00";
            } else {
                len0 = len.substring(2, 4);
                len1 = len.substring(0, 2);
            }
            String header = initHeader(diD, "07", len0, len1, "00");
            String result = (header + date).toUpperCase();
            try {
                //ArrayList arrayList = udpClient.startClient(result);
                JSONObject jsonParam1 = new JSONObject();
                jsonParam1.put("ss", result);
                RespEntity rest = rest(jsonParam1, "windowsServer", "startClient", "windowsServer", "POST");
                JSONObject dataRest = (JSONObject)rest.getData();
                JSONArray arrayList = dataRest.getJSONArray("data");
            /*RespEntity rest = rest(jsonParam1, "windowsServer", "startClient", "windowsServer", "POST");
            ArrayList arrayList = (ArrayList)rest.getData();*/
                IpSoundFileName IpSoundFileName = this.ipSoundFileNameMapper.selectList(new QueryWrapper<IpSoundFileName>().eq("filenumber", filenumberOld)).get(0);
                filename = IpSoundFileName.getFilename();
                if (arrayList.size() > 0) {
                    String data = (String)arrayList.get(0);
                    String subIdReverse = data.substring(32, 40);
                    String subId1 = subIdReverse.substring(0, 2);
                    String subId2 = subIdReverse.substring(2, 4);
                    String subId3 = subIdReverse.substring(4, 6);
                    String subId4 = subIdReverse.substring(6, 8);
                    subId = subId4 + subId3 + subId2 + subId1;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            for (String id : ids) {
                IpSoundPlaying ipSoundPlaying = new IpSoundPlaying();
                ipSoundPlaying.setId(UUID.randomUUID().toString());
                ipSoundPlaying.setFilename(filename);
                ipSoundPlaying.setSubid(subId.toUpperCase());
                ipSoundPlaying.setSubid(subId.toUpperCase());
                ipSoundPlaying.setDevicenumber(id);
                ipSoundPlaying.setFilenumber(filenumberOld);
                ipSoundPlaying.setEndtime(DateUtil.parse(endtime));
                ipSoundPlayingMapper.insert(ipSoundPlaying);
            }
        }
        //*************************************************************************************************************************************************
        return RespEntity.success();
    }

    /**
     * 终止播放
     * @param jsonParam
     * @return
     */
    @Async
    public RespEntity endPlay(JSONObject jsonParam) {
        String devicenumbers = jsonParam.getStr("devicenumber");
        String[] split = devicenumbers.split(",");
        for (String s : split) {
        //List<IpSoundPlaying> ipSoundPlayings = this.ipSoundPlayingMapper.selectList(new QueryWrapper<IpSoundPlaying>().eq("devicenumber", s));
        /*if (ipSoundPlayings.size() <= 0) {
            return RespEntity.fail("没有可以终止的任务");
        }*/
            //todo 如果查询条数大于1，则判断一下，删除
            //IpSoundPlaying ipSoundPlaying = ipSoundPlayings.get(0);
            //String id = ipSoundPlaying.getId();
            //String subIdReserve = ipSoundPlaying.getSubid();
            String header = initHeader(diD, "1C", "0C", "00", "01");
            String playerId1 = s.substring(0, 2);
            String playerId2 = s.substring(2, 4);
            String playerId3 = s.substring(4, 6);
            String playerId4 = s.substring(6, 8);
            String playerId = playerId4 + playerId3 + playerId2 + playerId1;
            try {
                //udpClient.startClient(header + subId);
                JSONObject jsonParam1 = new JSONObject();
                jsonParam1.put("ss", header + playerId + "00000000" + "00000000");
                RespEntity rest = rest(jsonParam1, "windowsServer", "startClient", "windowsServer", "POST");
                if (s != null && !s.equals("")) {
                    this.ipSoundPlayingMapper.delete(new QueryWrapper<IpSoundPlaying>().eq("devicenumber", s));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return RespEntity.success();
    }

    @Async
    public RespEntity setTaskVolume(JSONObject jsonParam) {
        String[] split = jsonParam.getStr("deviceNumber").split(",");
        for (String deviceNumber : split) {
            List<IpSoundPlaying> list = this.ipSoundPlayingMapper.selectList(new QueryWrapper<IpSoundPlaying>().eq("devicenumber", deviceNumber));
            if (list.size() <= 0) {
                return RespEntity.fail("该设备下没有正在播放的任务");
            }
            String subId = list.get(0).getSubid();
            //0～127
            int vol = jsonParam.getInt("vol");
            String volHex = hex10To16(vol);
            String header = initHeader(diD, "0B", "08", "00", "00");
            String body = subId.substring(6, 8) + subId.substring(4, 6) + subId.substring(2, 4) + subId.substring(0, 2) + volHex + "000000";
            JSONObject jsonParam1 = new JSONObject();
            jsonParam1.put("ss", header + body);
            RespEntity rest = rest(jsonParam1, "windowsServer", "startClient", "windowsServer", "POST");
            /*JSONObject json = (JSONObject)rest.getData();
            JSONArray arrayList = json.getJSONArray("data");*/
        }
        return RespEntity.success();
    }



    /**
     * 根据设备id设置音量
     * @param jsonParam
     * @return
     */
    @Async
    public RespEntity SetPlayerVolume(JSONObject jsonParam) {
        String[] split = jsonParam.getStr("deviceNumber").split(",");
        for (String deviceNumber : split) {
            /*List<IpSoundPlaying> list = this.ipSoundPlayingMapper.selectList(new QueryWrapper<IpSoundPlaying>().eq("devicenumber", deviceNumber));
            if (list.size() <= 0) {
                return RespEntity.fail("该设备下没有正在播放的任务");
            }
            String subId = list.get(0).getSubid();*/
            //0～127
            int vol = jsonParam.getInt("vol");
            int volRes = volumeChange(vol);
            String volHex = hex10To16(volRes);
            String header = initHeader(diD, "0C", "08", "00", "00");
            String body = deviceNumber.substring(6, 8) + deviceNumber.substring(4, 6) + deviceNumber.substring(2, 4) + deviceNumber.substring(0, 2) + volHex + "000000";
            JSONObject jsonParam1 = new JSONObject();
            jsonParam1.put("ss", header + body);
            RespEntity rest = rest(jsonParam1, "windowsServer", "startClient", "windowsServer", "POST");
            /*JSONObject json = (JSONObject)rest.getData();
            JSONArray arrayList = json.getJSONArray("data");*/
        }
        return RespEntity.success();
    }

    public static int volumeChange(int vol){
        int volumeChange = 0;
        if (vol == 0) {
            volumeChange = 127;
        } else {
            volumeChange = 100 - vol;
        }
        return volumeChange;
    }

    public static String hex10To16(int valueTen){
        String s = Integer.toHexString(valueTen);
        if (s.length() == 1) {
            return "0"+Integer.toHexString(valueTen);
        } else {
            return Integer.toHexString(valueTen);
        }
    }


    public static String makeChecksum(String hexdata) {
        if (hexdata == null || hexdata.equals("")) {
            return "00";
        }
        hexdata = hexdata.replaceAll(" ", "");
        int total = 0;
        int len = hexdata.length();
        if (len % 2 != 0) {
            return "00";
        }
        int num = 0;
        while (num < len) {
            String s = hexdata.substring(num, num + 2);
            total += Integer.parseInt(s, 16);
            num = num + 2;
        }
        return hexInt(total);
    }

    private static String hexInt(int total) {
        int a = total / 256;
        int b = total % 256;
        if (a > 255) {
            return hexInt(a) + format(b);
        }
        return format(a) + format(b);
    }

    private static String format(int hex) {
        String hexa = Integer.toHexString(hex);
        int len = hexa.length();
        if (len < 2) {
            hexa = "0" + hexa;
        }
        return hexa;
    }

    /**
     * 字符串转换为16进制字符串
     *
     * @param s
     * @return
     */
    public static String stringToHexString(String s) {
        String str = "";
        for (int i = 0; i < s.length(); i++) {
            int ch = (int) s.charAt(i);
            String s4 = Integer.toHexString(ch);
            str = str + s4;
        }
        return str;
    }

    /**
     * 将二进制转换成16进制
     *
     * @param buf
     * @return
     */
    public static String parseByte2HexStr(byte buf[]) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    /**
     * 将字符串转成ASCII方法
     * @param value
     * @return
     */
    public static String stringToAscii(String value)
    {
        StringBuffer sbu = new StringBuffer();
        char[] chars = value.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if(i != chars.length - 1)
            {
                sbu.append(hex10To16((int)chars[i]));
            }
            else {
                sbu.append(hex10To16((int)chars[i]));
            }
        }
        return sbu.toString().toUpperCase();
    }


    // 转化十六进制编码为字符串(中文乱码已解决)从十六进制字符串到字节数组转换
    public static String HexStringToBytes(String hexstr) {
        byte[] b = new byte[hexstr.length() / 2];
        int j = 0;
        for (int i = 0; i < b.length; i++) {
            char c0 = hexstr.charAt(j++);
            char c1 = hexstr.charAt(j++);
            b[i] = (byte) ((parse(c0) << 4) | parse(c1));
        }
        String store_name = "";
        try {
            store_name  = new String(b,"GB2312");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return store_name;
    }
    // 转化十六进制编码为字符串(中文乱码已解决)从十六进制字符串到字节数组转换
    private static int parse(char c) {
        if (c >= 'a')
            return (c - 'a' + 10) & 0x0f;
        if (c >= 'A')
            return (c - 'A' + 10) & 0x0f;
        return (c - '0') & 0x0f;
    }


    /**
     * 10进制时间转16进制时间
     * @param time
     * @return
     */
    public String getHexTime(String time) {

        //20210929000200
        String time0 = time.replace("-", "");
        String time1 = time0.replace(":", "");
        String time2 = time1.replace(" ", "");
        String year = time2.substring(2, 4);
        String month = time2.substring(4, 6);
        String day = time2.substring(6, 8);
        String hour = time2.substring(8, 10);
        String minute = time2.substring(10, 12);
        String second = time2.substring(12, 14);

        String yearHex = hex10To16(Integer.parseInt(year));
        String monthHex = hex10To16(Integer.parseInt(month));
        String dayHex = hex10To16(Integer.parseInt(day));
        String hourHex = hex10To16(Integer.parseInt(hour));
        String minuteHex = hex10To16(Integer.parseInt(minute));
        String secondHex = hex10To16(Integer.parseInt(second));
        return (yearHex + monthHex + dayHex + hourHex + minuteHex + secondHex).toUpperCase();

    }

    /**
     * splitAry方法<br>
     * @param ary 要分割的数组
     * @param subSize 分割的块大小
     * @return
     *
     */
    private static Object[] splitAry(String[] ary, int subSize) {
        int count = ary.length % subSize == 0 ? ary.length / subSize: ary.length / subSize + 1;

        List<List<String>> subAryList = new ArrayList<List<String>>();

        for (int i = 0; i < count; i++) {
            int index = i * subSize;
            List<String> list = new ArrayList<>();
            int j = 0;
            while (j < subSize && index < ary.length) {
                list.add(ary[index++]);
                j++;
            }
            subAryList.add(list);
        }

        Object[] subAry = new Object[subAryList.size()];

        for(int i = 0; i < subAryList.size(); i++){
            List<String> subList = subAryList.get(i);
            String[] subAryItem = new String[subList.size()];
            for(int j = 0; j < subList.size(); j++){
                subAryItem[j] = subList.get(j);
            }
            subAry[i] = subAryItem;
        }

        return subAry;
    }

    public static void main(String[] args) {
    }

}
